package com.benmei.weike.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;

/**
 * Created by lizhun on 15/12/23.
 * Modified by wangzheng on 17/02/18
 */
public class CommonUtil {
    private static Logger logger = Logger.getLogger(CommonUtil.class);
    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMM");
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
    private static SimpleDateFormat sdf_channel = new SimpleDateFormat("MMddHH");
    private static SimpleDateFormat sdf_time = new SimpleDateFormat("yyyy-MM-dd");
    private static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private static SimpleDateFormat sdf_day_for = new SimpleDateFormat("yyyyMMdd");

    private static Date date = new Date();

    public static Date getDate(String date) throws ParseException {
        return sdf_time.parse(date);
    }


    public static String substring(String source, int start, int end) {
        String result;
        try {
            result = source.substring(source.offsetByCodePoints(0, start),
                    source.offsetByCodePoints(0, end));
        } catch (Exception e) {
            result = "";
        }
        return result;
    }

    /**
     * 根据当前日期获得所在周的日期区间（周一和周日日期）
     * 传true获取周一  false周日
     *
     * @return Timestamp
     * @throws ParseException
     * @author lizhun
     */
    public static Timestamp getTimeInterval(boolean flag) throws ParseException {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        // 判断要计算的日期是否是周日，如果是则减一天计算周六的，否则会出问题，计算到下一周去了
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        // System.out.println("要计算日期为:" + sdf.format(cal.getTime())); // 输出要计算日期
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int day = cal.get(Calendar.DAY_OF_WEEK);
        if (flag) {
            // 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
            cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
            // System.out.println("所在周星期一的日期：" + imptimeBegin);
        } else {
            cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
            cal.add(Calendar.DATE, 6);
            // System.out.println("所在周星期日的日期：" + imptimeEnd);
        }

        String time = sdf_time.format(cal.getTime()) + " 00:00:00";
        Date date = sdf_day.parse(time);
        return new Timestamp(date.getTime());
    }

    /**
     * 根据当前日期获得上周的日期区间（上周周一和周日日期）
     * 传true获取周一  false周日
     *
     * @return Timestamp
     * @author lizhun
     */
    public static Timestamp getLastWeekStartTime(boolean flag) throws ParseException {
        Calendar calendar = Calendar.getInstance();
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;

        if (flag) {
            int offset = 1 - dayOfWeek;
            calendar.add(Calendar.DATE, offset - 7);
        } else {
            int offset = 7 - dayOfWeek;
            calendar.add(Calendar.DATE, offset - 7);
        }
        String time = sdf_time.format(calendar.getTime()) + " 00:00:00";
        Date date = sdf_day.parse(time);
        return new Timestamp(date.getTime());
    }

    /**
     * @return String
     * @Purpose 计算预约时间
     * @author lizhun
     * @version 1.0
     */
    public static Timestamp getRerceveTime(int time, int day) throws ParseException {
        Calendar cal = Calendar.getInstance();//使用默认时区和语言环境获得一个日历。
        cal.add(Calendar.DAY_OF_MONTH, +day);
        String rerveve_time = "";
        if (time >= 10) {
            rerveve_time = sdf_time.format(cal.getTime()) + " " + time + ":00:00";
        } else {
            rerveve_time = sdf_time.format(cal.getTime()) + " 0" + time + ":00:00";
        }
        Date date = sdf_day.parse(rerveve_time);
        return new Timestamp(date.getTime());
    }

    /**
     * @return String
     * @Purpose 计算预约时间
     * @author lizhun
     * @Modifier wangzhegn
     * @version 4.1
     */
    public static Timestamp getRerceveTime(int time, String reserve_time) throws ParseException {
        long times = sdf_time.parse(reserve_time).getTime();
        times = times + time * 60 * 60 * 1000;
        return new Timestamp(times);
    }

    /**
     * @return String
     * @Purpose 根据时间判断是否与当前时间为4小时以为
     * @author lizhun
     * @version 1.0
     */
    public static boolean getTimeResult(Timestamp timestamp) {
        boolean flag = false;
        if (timestamp.getTime() - System.currentTimeMillis() >= 4 * 60 * 60 * 1000) {
            flag = true;
        }
        return flag;
    }

    /**
     * @return String
     * @Purpose 根据时间判断是否与当前时间为1小时以内(false是, true不是)
     * @author lizhun
     * @version 1.0
     */
    public static boolean getTimeCancle(Timestamp timestamp) {
        boolean flag = false;
        if (timestamp.getTime() - System.currentTimeMillis() >= 60 * 60 * 1000) {
            flag = true;
        }
        return flag;
    }

    /**
     * 根据时间判断周几
     *
     * @param date
     * @return
     */
    public static Integer getWeekday(String date) {//必须yyyy-MM-dd
        int result = 1;

        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
        Date d = null;
        try {
            d = sd.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        result = c.get(Calendar.DAY_OF_WEEK) - 1;
        return result == 0 ? 7 : result;
    }

    /**
     * 根据时间判断周几
     *
     * @param date
     * @return
     */
    public static Integer getWeekday(Date date) {
        int result = 1;
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        result = c.get(Calendar.DAY_OF_WEEK) - 1;
        return result == 0 ? 7 : result;
    }


    public static String getMonth(Date date) {
        return simpleDateFormat.format(date);
    }

    /**
     * @return String
     * @Purpose 获取当前日期
     * @author lizhun
     * @version 1.0
     */
    public static String getDay() {
        return sdf_day_for.format(date);
    }

    /**
     * @return String
     * @Purpose 生成token
     * @author lizhun
     * @version 1.0
     */
    public static String getToken() {
        UUID token = UUID.randomUUID();
        return "" + token;
    }

    /**
     * @return String
     * @Purpose 生成邀请码
     * @author lizhun
     * @version 1.0
     */
    public static String getInviteCode() {
        String code = "" + (int) ((Math.random() * 9 + 1) * 100);
        String dateString = code + sdf.format(date);
        Long result = Long.valueOf(dateString);
        String inviteCode = result.toHexString(result);
        return inviteCode.substring(0, inviteCode.length() - 4);
    }

    /**
     * @return String
     * @Purpose 生成直播频道
     * @author lizhun
     * @version 1.0
     */
    public static String getLiveChannel() {
        String code = "" + (int) ((Math.random() * 9 + 1) * 100);
        String dateString = code + sdf_channel.format(date);
        return dateString;
    }

    /**
     * @return String
     * @Purpose 计算年龄
     * @author lizhun
     * @version 1.0
     */
    public static int getAge(Date dateOfBirth) {
        int age = 0;
        Calendar born = Calendar.getInstance();
        Calendar now = Calendar.getInstance();
        if (dateOfBirth != null) {
            now.setTime(new Date());
            born.setTime(dateOfBirth);
            if (born.after(now)) {
                throw new IllegalArgumentException(
                        "Can't be born in the future");
            }
            age = now.get(Calendar.YEAR) - born.get(Calendar.YEAR);
            if (now.get(Calendar.DAY_OF_YEAR) < born.get(Calendar.DAY_OF_YEAR)) {
                age -= 1;
            }
        }
        return age;
    }

    /**
     * @return String
     * @Purpose 获取时间
     * @author lizhun
     * @version 1.0
     */
    public static Long getTime(int set_type, int size) {
        int dateSize = 0;
        switch (set_type) {
            case 1:
                dateSize = 1;
                break;
            case 2:
                dateSize = 7;
                break;
            case 3:
                dateSize = 31;
                break;
            case 4:
                dateSize = 365;
                break;

            default:
                break;
        }
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, dateSize * size);
//        Date date = new Date();
//        date.setDate(dateSize*size);
        return c.getTimeInMillis();
    }

    /**
     * @return String
     * @Purpose 获取编号
     * @author lizhun
     * @version 1.0
     */
    public static String getOrderNub() {
        String orderNub = sdf.format(date).substring(2, 12);

        String code = "";
        while (code.length() < 5) {
            code += (int) (Math.random() * 10);
        }
        orderNub = orderNub + code;
        return orderNub;
    }

    /**
     * 判断时间是否在时间段内
     *
     * @return
     */
    public static boolean isInDate(Date time, String startTime,
                                   String endTime) {
        Boolean b = false;
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        String nowTime = time.getHours() + ":" + time.getMinutes() + ":" + time.getSeconds();
        try {
            time = sdf.parse(nowTime);
            Date startTimes = sdf.parse(startTime);
            Date endTimes = sdf.parse(endTime);
            if (startTimes.after(endTimes)) {
                Date n = startTimes;
                startTimes = endTimes;
                endTimes = n;
            }
            if (time.after(startTimes) || time.equals(startTimes)) {
                if (time.before(endTimes) || time.equals(endTimes)) {
                    b = true;
                } else {
                    b = false;
                }
            } else {
                b = false;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return b;
    }

    public static int getMinute(Date firstDate, Date secondDate, String time) {
        Calendar c = Calendar.getInstance();
        int second = 0;
        c.setTime(secondDate);
        int year = c.get(Calendar.YEAR);
        int mouth = c.get(Calendar.MONTH) + 1;
        int day = c.get(Calendar.DATE);

        String endtime = year + "-" + mouth + "-" + day + " " + time;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            secondDate = sdf.parse(endtime);
            Long l = (firstDate.getTime() - secondDate.getTime());
            second = (int) (l / 1000 / 60);
            if (l % 60 != 0) {
                second = second + 1;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return second;
    }

    public static int getHour(Date date) {
        int start_time = 0;
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        start_time = c.get(Calendar.HOUR_OF_DAY);

        return start_time;
    }

    public static Date addData(Date currentDate, int reserve_limit_days) {
        Calendar cal = Calendar.getInstance();//使用默认时区和语言环境获得一个日历。
        cal.setTime(currentDate);
        cal.add(Calendar.DAY_OF_MONTH, reserve_limit_days);
        return cal.getTime();
    }

    public static String formatYMD(Date date) {
        return sdf_time.format(date);
    }

    /**
     * @param startDate
     * @param endDate
     * @return
     * @Purpose 判断两个日期相差的天数
     * @version 4.1
     * @author Peter
     */
    public static long distanceDays(Date startDate, Date endDate) {
        long n = (endDate.getTime() - startDate.getTime()) / (24 * 60 * 60 * 1000);
        return n;
    }

    public static String starMiddleName(String name) {
        if (StringUtils.isBlank(name)) {
            return name;
        }
        return CommonUtil.substring(name, 0, 1) + "****" + CommonUtil.substring(name, name.length() - 1, name.length());
    }
}
